Projeto base de aprendizado de máquina
Projeto de Aprendizado de máquina
Para a realização do projeto de aprendizado de máquina, foi escolhido o conjunto de dados IRIS nativo da biblioteca scikit-learn. Foi criado um documento Rmarkdown, porém codificado em python com o auxílio da biblioteca reticulate.
Coleta de dados
Primeiramente, foi importado as classes necessárias para o projeto. A estrutura de importação da linguagem python se estrutura em módulos. Um módulo é um arquivo contendo uma função em específico que podemos utiliza-la no nosso código:
- from nome_do_arquivo import nome_da_função|classe
from sklearn.datasets import load_iris
from sklearn.model_selection import train_test_split
from sklearn.impute import SimpleImputer
from sklearn.pipeline import Pipeline
from sklearn.preprocessing import StandardScaler
import pandas as pd
import plotly.express as px
dados = load_iris().data
colunas = load_iris().feature_names
df = pd.DataFrame(data = dados, columns = colunas)
df['target'] = load_iris().targetDivisão dos dados
Antes de realizar qualquer coisa, deve-se dividir os dados em treino e teste. Isso é feito com o objetivo de evitar o viés de espionagem, onde acabamos por ajustar o modelo aos dados de teste. Portanto, deve-se realizar todo o processo de análise, transoformação e comparação de modelos com os dados de treino, para que no final se utlize os dados de teste.
Foi usado o parâmetro stratify para dividir os dados respeitando o desbalanceamento dos rótulos.
df_treino,df_teste = train_test_split(df, stratify = df['target'])Análise Exploratória
Foi feito uma análise descritiva bem simples com algumas colunas.
print(df_treino.describe())## sepal length (cm) sepal width (cm) ... petal width (cm) target
## count 112.000000 112.000000 ... 112.000000 112.000000
## mean 5.854464 3.072321 ... 1.200893 0.991071
## std 0.846497 0.452064 ... 0.767175 0.821946
## min 4.300000 2.000000 ... 0.100000 0.000000
## 25% 5.100000 2.800000 ... 0.300000 0.000000
## 50% 5.800000 3.000000 ... 1.300000 1.000000
## 75% 6.500000 3.400000 ... 1.800000 2.000000
## max 7.900000 4.400000 ... 2.500000 2.000000
##
## [8 rows x 5 columns]
df_treino.head(5)## sepal length (cm) sepal width (cm) ... petal width (cm) target
## 20 5.4 3.4 ... 0.2 0
## 122 7.7 2.8 ... 2.0 2
## 98 5.1 2.5 ... 1.1 1
## 84 5.4 3.0 ... 1.5 1
## 101 5.8 2.7 ... 1.9 2
##
## [5 rows x 5 columns]
px.histogram(df_treino['sepal length (cm)'])px.histogram(df_treino['sepal width (cm)'])px.histogram(df_treino['petal length (cm)'])px.histogram(df_treino['petal width (cm)'])px.bar(df_treino['target'].value_counts().sort_values(ascending = False))Imputação e transformação
Para a realização da imputação dos dados, deve-se primeiro fazer para os dados de treino e depois para os de teste. Como não sabemos quais dados estão nulos no teste, realizaremos do mesmo jeito, já que o algoritmo de imputação identifica quais colunas possuem ou não valores nulos.
x_treino = df_treino.drop(['target'], axis = 1)
y_treino = df_treino['target']A classe Pipeline tem como função juntar os componentes de imputação e transformação dos dados de forma a automatizar processos.
pipe = Pipeline([
('imputer', SimpleImputer(strategy = 'mean') ),
('scale', StandardScaler())
])
x_treino_preparado = pipe.fit_transform(x_treino)Treinamento e Seleção do Modelo
Foi utilizado as principais métricas de classificação:
- Precision;
- Recall
- F1-score
from sklearn.model_selection import cross_val_predict
from sklearn.metrics import classification_report
from sklearn.ensemble import RandomForestClassifier
pred = cross_val_predict(RandomForestClassifier(),x_treino_preparado,y_treino, cv = 4)
print(classification_report(y_treino,pred))## precision recall f1-score support
##
## 0 1.00 1.00 1.00 38
## 1 0.92 0.95 0.93 37
## 2 0.94 0.92 0.93 37
##
## accuracy 0.96 112
## macro avg 0.96 0.95 0.95 112
## weighted avg 0.96 0.96 0.96 112
from sklearn.neighbors import KNeighborsClassifier
pred = cross_val_predict(KNeighborsClassifier(),x_treino_preparado,y_treino, cv = 4)
print(classification_report(y_treino,pred))## precision recall f1-score support
##
## 0 1.00 1.00 1.00 38
## 1 0.95 0.95 0.95 37
## 2 0.95 0.95 0.95 37
##
## accuracy 0.96 112
## macro avg 0.96 0.96 0.96 112
## weighted avg 0.96 0.96 0.96 112
from sklearn.svm import SVC
pred = cross_val_predict(SVC(),x_treino_preparado,y_treino, cv = 4)
print(classification_report(y_treino,pred))## precision recall f1-score support
##
## 0 1.00 0.97 0.99 38
## 1 0.95 0.95 0.95 37
## 2 0.95 0.97 0.96 37
##
## accuracy 0.96 112
## macro avg 0.96 0.96 0.96 112
## weighted avg 0.96 0.96 0.96 112
Foi observado que o algoritmo Random Forest se mostrou superior.
Aprimoramento do Modelo
Para o aprimoramento do modelo, foi utilizado a técnica de pesquisa em grade com dois hiperparâmetros do Random Forest.
from sklearn.model_selection import GridSearchCV
random_grid = {'n_estimators': [200,300],
'max_features': [3,4]
}
grade = GridSearchCV(RandomForestClassifier(), param_grid = random_grid, cv =4)
grade.fit(x_treino_preparado,y_treino)## GridSearchCV(cv=4, estimator=RandomForestClassifier(),
## param_grid={'max_features': [3, 4], 'n_estimators': [200, 300]})
modelo_final = grade.best_estimator_Teste final
Para o teste final, foi usado a classe Pipeline e o modelo final encontrado na pesquisa em grade.
x_teste = df_teste.drop(['target'], axis = 1)
y_teste = df_teste['target']
x_teste_preparado = pipe.transform(x_teste)
modelo_final.fit(x_treino_preparado, y_treino)## RandomForestClassifier(max_features=3, n_estimators=200)
pred_final = modelo_final.predict(x_teste_preparado)
print(classification_report(y_teste,pred_final))## precision recall f1-score support
##
## 0 1.00 1.00 1.00 12
## 1 0.87 1.00 0.93 13
## 2 1.00 0.85 0.92 13
##
## accuracy 0.95 38
## macro avg 0.96 0.95 0.95 38
## weighted avg 0.95 0.95 0.95 38